package Flap::Object;
use Flap::Core qw/-s -w/;
use Cwd;

sub DESTROY { delete $Flap::OBJECT{$_[0]} }

sub _class_ { ref $_[0] || $_[0] }

sub _code_ {
    no strict 'refs';
    *{$_[0]->_class_.'::'.$_[1]}{CODE}
}

sub _data_ { $Flap::OBJECT{$_[0]} ||= {} }

sub _define_method_ {
    no strict 'refs';
    *{$_[0]->_class_.'::'.$_[1]} = $_[2];
}

sub _dump_ {
    my $self = shift;
    Flap->Util->dump(@_ ? shift : $self);
}

sub _global_ { $Flap::G{ref $_[0] || $_[0]} ||= {} }

sub _isa_ {
    shift if @_ > 2;
    UNIVERSAL::isa(@_);
}

sub _mk_accessors_ {
    my $class = shift->_class_;
    foreach(@_){
        my $k = $_;
        my $code = sub{
            return $_[0]->{$k} if @_ == 1;
            $_[0]->{$k} = $_[1];
            $_[0];
        };
        no strict 'refs';
        *{$class."::$_"} = $code;
    }
}

sub _new_ {
    my $obj = bless $_[1], ref $_[0] || $_[0];
    $Flap::OBJECT{$obj} = undef;
    $obj;
}

sub OS { shift->project->OS }

sub project_root { $Flap::G{$_[0]->project}->{project_root} ||= $_[0]->project->root_dir }

sub _parent_class_ {
    my $class = shift->_class_;
    substr($class, 0, rindex($class, '::'));
}

sub _symbol_ { \($Flap::G{symbol}{$_[1]} ||= $_[1]) }

sub Util { shift->project->Util }

sub _weaken_ { require Scalar::Util; Scalar::Util::weaken($_[1]) }

1;
